package org.hgvc.webapp.ets.spring.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.hgvc.webapp.ets.bo.ActionBulletin;
import org.hgvc.webapp.ets.bo.Agent;
import org.hgvc.webapp.ets.bo.AgentCommission;
import org.hgvc.webapp.ets.bo.AgentCommissionPayment;
import org.hgvc.webapp.ets.bo.Agreement;
import org.hgvc.webapp.ets.bo.AgreementControl;
import org.hgvc.webapp.ets.bo.CommissionPaymentSchema;
import org.hgvc.webapp.ets.bo.CommissionSchema;
import org.hgvc.webapp.ets.bo.CommissionSchemaMembership;
import org.hgvc.webapp.ets.bo.CommissionSchemaPaymentRange;
import org.hgvc.webapp.ets.bo.DocControl;
import org.hgvc.webapp.ets.bo.Membership;
import org.hgvc.webapp.ets.bo.Payment;
import org.hgvc.webapp.ets.constant.ActionBulletinConstant;
import org.hgvc.webapp.ets.constant.AgentConstant;
import org.hgvc.webapp.ets.constant.CommonConstant;
import org.hgvc.webapp.ets.constant.SystemConstant;
import org.hgvc.webapp.ets.constant.TerminateConstant;
import org.hgvc.webapp.ets.jsf.beans.admin.AdminAgentRegApprBean;
import org.hgvc.webapp.ets.spring.dao.AgentHbmDao;
import org.jocsb.base.bo.User;
import org.jocsb.base.exception.BaseException;
import org.jocsb.base.util.SpringUtils;
import org.jocsb.base.util.SystemUtil;


public class AgentServiceImpl implements AgentService {

	private AgentHbmDao dao;
	private AdminService adminService;
	private MasterSetupService setupService;
	private SystemService systemService;
	private TerminateProcService terminateProcService;
	

	public void setTerminateProcService(TerminateProcService terminateProcService) {
		this.terminateProcService = terminateProcService;
	}
	public void setSystemService(SystemService systemService) {
		this.systemService = systemService;
	}
	public void setDao(AgentHbmDao dao) {
		this.dao = dao;
	}
	public void setAdminService(AdminService adminService) {
		this.adminService = adminService;
	}
	public void setSetupService(MasterSetupService setupService) {
		this.setupService = setupService;
	}

	public void saveAgentAgreementTransfer(Agent agentFrom,Agreement agreements, Agent toAgent){
		
	}

	public void saveTerminateAgent(String agentId, User user) throws Exception{
		
		Agent agent = (Agent)getAgentById(agentId);
		agent.setStatus(AgentConstant.AGENT_STATUS_TERMINATED);
		agent.setModifiedBy(user);
		agent.setModifiedDate(new Date());
		agent.getRefUser().setStatus(CommonConstant.STATUS_NO);
		agent.getRefUser().setModifiedBy(user);
		agent.getRefUser().setModifiedDate(new Date());
		
		dao.update(agent);
		dao.update(agent.getRefUser());
		
		terminateProcService.saveTerminateLog(TerminateConstant.TERMINATE_TYPE_AGENT, 
				TerminateConstant.TERMINATE_TYPE_AGENT+" account is "+TerminateConstant.TERMINATED, 
				agent.getAgentRegNo()+"/"+agent.getCompName()+"/"+agent.getEmail(),user);
		
	}
	
	public String agentRegistration(Agent agent,boolean isOnlienReg,User creadtedUser)throws BaseException{
		try{
			if(isOnlienReg){
				agent.setRegType(AgentConstant.AGENT_REG_ONLINE);
			}else{
				agent.setRegType(AgentConstant.AGENT_REG_OFFLINE);
				agent.setCreatedBy(creadtedUser);
			}
			agent.setCreatedDate(new Date());
			agent.setStatus(AgentConstant.AGENT_STATUS_PENDING_APPROVAL_REG);
			//save partner
			String regNo = getDocumentNo(CommonConstant.DOC_TYPE_AGENT_REG);
			agent.setAgentRegNo(regNo);

			//create temp user for particular user
			User user = adminService.createNewUserWithRole(agent.getEmail(), SystemConstant.DEFAULT_PASSWORD
					, SystemConstant.AGENT_TEMP_ROLE, SystemConstant.SYSTEM_USER);
			agent.setRefUser(user);
			dao.save(agent);
			//create action bullentin to admin
			ActionBulletin ab = new ActionBulletin();
			ab.setActionCode(SpringUtils.getMessage("ab.agent.reg.pending.approval", new Object[]{agent.getAgentRegNo()}));
			ab.setActionParam1(agent.getAgentId());
			ab.setActionNo(SystemUtil.getUniqueCode());
			ab.setActionBean(AdminAgentRegApprBean.BEAN_NAME);
			ab.setActionMethod(AdminAgentRegApprBean.AB_INVOKE_ACTION_METHOD);
			ab.setIsDeleted(CommonConstant.NOT_DELETED);
			ab.setType(ActionBulletinConstant.AB_ACK_TYPE);
			ab.setCreatedBy(SystemConstant.SYSTEM_USER);
			ab.setCreatedDate(new Date());
			systemService.createActionBulletinByRoles(ab, SystemConstant.ADMIN_ROLE);
			//systemService.createActionBulletinByRoles(ab, SystemConstant.MEMBER_SERVICE_ROLE);//Added By Jacky 19-OCT-2008 2137
			systemService.createActionBulletinByRoles(ab, SystemConstant.FINANCE_ADMIN_ROLE);//Bug fixed by Jacky 31-OCT-2008 1432
			
			return regNo;
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.agent.registration", new Object[]{}));
		}
	}

	public Agent getAgentByUserId(String userId)throws BaseException{
		try{
			return dao.getAgentByUserId(userId);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.agent", new Object[]{}));
		}
	}

	public Agent getAgentById(String id)throws BaseException{
		try{
			return (Agent)dao.getObject(Agent.class, id);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.agent", new Object[]{}));
		}
	}

	public synchronized String getDocumentNo(String type)throws BaseException{
		String documentNo="";
		try{
			DocControl docControl = setupService.getDocControlByType(type);
			if (docControl==null)
				throw new BaseException(SpringUtils.getMessage("error.doc.type.not.config", new Object[]{type}));

			StringBuffer numberBuf =new StringBuffer();
			numberBuf.append(docControl.getPrefix());
			long counter = docControl.getNumber()+1;
			long currentSize=new Long(String.valueOf(counter).length()).longValue();
			long size = docControl.getSize();
			for (long l=currentSize;l<size;l++){
				numberBuf.append("0");
			}
			numberBuf.append(counter);
			documentNo = numberBuf.toString();
			docControl.setNumber(counter);
			setupService.updateDocControl(docControl);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.generate.doc.no", new Object[]{type}));
		}
		return documentNo;
	}

	//master
	//commission payment schema
	public List<CommissionPaymentSchema> getCommissionPaymentSchemaListType(String type)throws BaseException{
		try{
			return dao.getCommissionPaymentSchemaWithType(type);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.commission.payment.schema", new Object[]{}));
		}
	}

	public List<CommissionPaymentSchema> getCommissionPaymentSchemaListAgentId(String agentId)throws BaseException{
		try{
			return dao.getCommissionPaymentSchemaWithAgentId(agentId);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.commission.payment.schema", new Object[]{}));
		}
	}

	public void createCommissionPaymentSchemaType(CommissionPaymentSchema schema,User user)throws BaseException{
		try{

			List<CommissionPaymentSchema> list = dao.getCommissionPaymentSchemaWithTypeCodeName(schema.getType(), schema.getCode(), schema.getName());
			if(list.size()>0){
				throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.payment.schema", new Object[]{}));
			}

			schema.setCreatedBy(user);
			schema.setCreatedDate(new Date());
			schema.setIsDeleted(CommonConstant.NOT_DELETED);
			dao.save(schema);

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.create.commission.payment.schema", new Object[]{}));
		}
	}

	public void createCommissionPaymentSchemaAgent(CommissionPaymentSchema schema,User user,Agent agent)throws BaseException{
		try{

			List<CommissionPaymentSchema> list = dao.getCommissionPaymentSchemaWithAgentIdCodeName(agent.getAgentId(), schema.getCode(), schema.getName());
			if(list.size()>0){
				throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.payment.schema", new Object[]{}));
			}

			schema.setCreatedBy(user);
			schema.setCreatedDate(new Date());
			schema.setIsDeleted(CommonConstant.NOT_DELETED);
			schema.setAgent(agent);
			dao.save(schema);

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.create.commission.payment.schema", new Object[]{}));
		}
	}

	public void editCommissionPaymentSchemaType(CommissionPaymentSchema schema,User user)throws BaseException{
		try{

			List<CommissionPaymentSchema> list = dao.getCommissionPaymentSchemaWithTypeCodeName(schema.getType(), schema.getCode(), schema.getName());
			if(list.size()>0){
				for(CommissionPaymentSchema s:list){
					if(!s.getCommPaymentSchId().equalsIgnoreCase(schema.getCommPaymentSchId())){
						throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.payment.schema", new Object[]{}));
					}
				}
			}
			schema.setModifiedBy(user);
			schema.setModifiedDate(new Date());

			dao.merge(schema);

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.edit.commission.payment.schema", new Object[]{}));
		}
	}

	public void editCommissionPaymentSchemaAgent(CommissionPaymentSchema schema,User user,Agent agent)throws BaseException{
		try{

			List<CommissionPaymentSchema> list = dao.getCommissionPaymentSchemaWithAgentIdCodeName(agent.getAgentId(), schema.getCode(), schema.getName());
			if(list.size()>0){
				for(CommissionPaymentSchema s:list){
					if(!s.getCommPaymentSchId().equalsIgnoreCase(schema.getCommPaymentSchId())){
						throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.payment.schema", new Object[]{}));
					}
				}
			}
			schema.setModifiedBy(user);
			schema.setModifiedDate(new Date());
			dao.merge(schema);

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.edit.commission.payment.schema", new Object[]{}));
		}
	}
	public void deleteCommissionPaymentSchema(List<CommissionPaymentSchema> deleteList,User user)throws BaseException{
		try{

			for(CommissionPaymentSchema c:deleteList){
				if(c.isMarkAsAction()){
					c.setModifiedBy(user);
					c.setModifiedDate(new Date());
					c.setIsDeleted(CommonConstant.IS_DELETED);
					dao.update(c);
				}
			}
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.delete.commission.payment.schema", new Object[]{}));
		}
	}


	//commission schema
	public List<CommissionSchema> getCommissionSchemaListType(String type)throws BaseException{
		try{
			return dao.getCommissionSchemaWithType(type);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.commission.schema", new Object[]{}));
		}
	}
	public List<CommissionSchema> getCommissionSchemaListAgentId(String agentId)throws BaseException{
		try{
			return dao.getCommissionSchemaWithAgentId(agentId);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.commission.schema", new Object[]{}));
		}
	}

	public List<CommissionSchemaPaymentRange> getCommissionSchemaPaymentRangeBySchId(String id)throws BaseException{
		try{
			return dao.getCommissionSchemaPaymentRangeBySchId(id);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.commission.schema.range", new Object[]{}));
		}
	}

	public List<CommissionSchemaMembership> getCommissionSchemaMembershipBySchId(String id)throws BaseException{
		try{
			return dao.getCommissionSchemaMembershipBySchId(id);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.commission.schema.membership", new Object[]{}));
		}
	}

	public void createCommissionSchemaType(CommissionSchema schema,User user,List<CommissionSchemaPaymentRange> rlist
			,List<CommissionSchemaMembership> mlist)throws BaseException{
		try{

			List<CommissionSchema> list = dao.getCommissionSchemaWithTypeCodeName(schema.getType(), schema.getCode(), schema.getName());
			if(list.size()>0){
				throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.schema", new Object[]{}));
			}

			schema.setCreatedBy(user);
			schema.setCreatedDate(new Date());
			schema.setIsDeleted(CommonConstant.NOT_DELETED);
			dao.save(schema);
			if(schema.getCommissionType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
				for(CommissionSchemaPaymentRange r:rlist){
					r.setCreatedBy(user);
					r.setCreatedDate(new Date());
					r.setIsDeleted(CommonConstant.NOT_DELETED);
					r.setCommissionSchema(schema);
					dao.save(r);
				}
			}else{
				for(CommissionSchemaMembership m:mlist){
					m.setCreatedBy(user);
					m.setCreatedDate(new Date());
					m.setIsDeleted(CommonConstant.NOT_DELETED);
					m.setCommSch(schema);
					dao.save(m);
				}
			}


		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.create.commission.schema", new Object[]{}));
		}
	}

	public void createCommissionSchemaAgent(CommissionSchema schema,User user,List<CommissionSchemaPaymentRange> rlist
			,List<CommissionSchemaMembership> mlist,Agent agent)throws BaseException{
		try{

			List<CommissionSchema> list = dao.getCommissionSchemaWithAgentIdCodeName(agent.getAgentId(),schema.getCode(),schema.getName());
			if(list.size()>0){
				throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.schema", new Object[]{}));
			}

			schema.setCreatedBy(user);
			schema.setCreatedDate(new Date());
			schema.setAgent(agent);
			schema.setIsDeleted(CommonConstant.NOT_DELETED);
			dao.save(schema);
			if(schema.getCommissionType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
				for(CommissionSchemaPaymentRange r:rlist){
					r.setCreatedBy(user);
					r.setCreatedDate(new Date());
					r.setIsDeleted(CommonConstant.NOT_DELETED);
					r.setCommissionSchema(schema);
					dao.save(r);
				}
			}else{
				for(CommissionSchemaMembership m:mlist){
					m.setCreatedBy(user);
					m.setCreatedDate(new Date());
					m.setIsDeleted(CommonConstant.NOT_DELETED);
					m.setCommSch(schema);
					dao.save(m);
				}
			}

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.create.commission.schema", new Object[]{}));
		}
	}

	public void editCommissionSchemaType(CommissionSchema schema,User user,List<CommissionSchemaPaymentRange> rlist
			,List<CommissionSchemaMembership> mlist)throws BaseException{
		try{

			List<CommissionSchema> list = dao.getCommissionSchemaWithTypeCodeName(schema.getType(), schema.getCode(), schema.getName());
			if(list.size()>0){
				for(CommissionSchema s:list){
					if(!s.getCommSchId().equalsIgnoreCase(schema.getCommSchId())){
						throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.schema", new Object[]{}));
					}
				}
			}
			schema.setModifiedBy(user);
			schema.setModifiedDate(new Date());
			dao.merge(schema);

			dao.deleteCommissionSchemaPaymentRangeBySchId(schema.getCommSchId());
			dao.deleteCommissionSchemaMembershipBySchId(schema.getCommSchId());

			/*for(CommissionSchemaPaymentRange r:rlist){
				r.setCommSchPayRangeId(null);
				r.setCreatedBy(user);
				r.setCreatedDate(new Date());
				r.setIsDeleted(CommonConstant.NOT_DELETED);
				r.setCommissionSchema(schema);
				dao.save(r);
			}*/
			if(schema.getCommissionType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
				for(CommissionSchemaPaymentRange r:rlist){
					r.setCreatedBy(user);
					r.setCreatedDate(new Date());
					r.setIsDeleted(CommonConstant.NOT_DELETED);
					r.setCommissionSchema(schema);
					dao.save(r);
				}
			}else{
				for(CommissionSchemaMembership m:mlist){
					m.setCreatedBy(user);
					m.setCreatedDate(new Date());
					m.setIsDeleted(CommonConstant.NOT_DELETED);
					m.setCommSch(schema);
					dao.save(m);
				}
			}

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.edit.commission.schema", new Object[]{}));
		}
	}

	public void editCommissionSchemaAgent(CommissionSchema schema,User user,List<CommissionSchemaPaymentRange> rlist
			,List<CommissionSchemaMembership> mlist,Agent agent)throws BaseException{
		try{

			List<CommissionSchema> list = dao.getCommissionSchemaWithAgentIdCodeName(agent.getAgentId(),schema.getCode(),schema.getName());
			if(list.size()>0){
				for(CommissionSchema s:list){
					if(!s.getCommSchId().equalsIgnoreCase(schema.getCommSchId())){
						throw new BaseException(SpringUtils.getMessage("error.duplicate.commission.schema", new Object[]{}));
					}
				}
			}
			schema.setModifiedBy(user);
			schema.setModifiedDate(new Date());
			dao.merge(schema);

			dao.deleteCommissionSchemaPaymentRangeBySchId(schema.getCommSchId());
			dao.deleteCommissionSchemaMembershipBySchId(schema.getCommSchId());
			/*for(CommissionSchemaPaymentRange r:rlist){
				r.setCommSchPayRangeId(null);
				r.setCreatedBy(user);
				r.setCreatedDate(new Date());
				r.setIsDeleted(CommonConstant.NOT_DELETED);
				r.setCommissionSchema(schema);
				dao.save(r);
			}*/
			if(schema.getCommissionType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
				for(CommissionSchemaPaymentRange r:rlist){
					r.setCreatedBy(user);
					r.setCreatedDate(new Date());
					r.setIsDeleted(CommonConstant.NOT_DELETED);
					r.setCommissionSchema(schema);
					dao.save(r);
				}
			}else{
				for(CommissionSchemaMembership m:mlist){
					m.setCreatedBy(user);
					m.setCreatedDate(new Date());
					m.setIsDeleted(CommonConstant.NOT_DELETED);
					m.setCommSch(schema);
					dao.save(m);
				}
			}

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.edit.commission.schema", new Object[]{}));
		}
	}

	public void deleteCommissionSchemaType(List<CommissionSchema> deleteList,User user)throws BaseException{
		try{

			for(CommissionSchema c:deleteList){
				if(c.isMarkAsAction()){
					c.setModifiedBy(user);
					c.setModifiedDate(new Date());
					c.setIsDeleted(CommonConstant.IS_DELETED);
					dao.update(c);
				}
				dao.deleteCommissionSchemaPaymentRangeBySchId(c.getCommSchId());
			}
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.delete.commission.schema", new Object[]{}));
		}
	}

	public List<Membership> getMembershipList()throws BaseException{
		try{
			return dao.getMembershipList();
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.membership", new Object[]{}));
		}
	}

	//aprrove agent registration
	public void approveAgentRegistration(Agent agent,AgreementControl control, User approver,String reason,String code,String actionNo)throws BaseException{
		try{
			//duplicate code
			List<Agent> list = dao.getAgentByCode(code);
			if(list.size()>0){
				throw new BaseException(SpringUtils.getMessage("error.duplicate.agent.code", new Object[]{}));
			}

			agent.setStatus(AgentConstant.AGENT_STATUS_APPROVE_AGENT);
			agent.setModifiedBy(approver);
			agent.setModifiedDate(new Date());
			agent.setReason(reason);
			agent.setCode(code);
			agent.setIsDeleted(CommonConstant.NOT_DELETED);
			agent.setAgentType(AgentConstant.AGENT_LEVEL_1);
			dao.update(agent);

			if(control!=null){
				control.setAgent(agent);
				control.setCreatedBy(approver);
				control.setCreatedDate(new Date());
				dao.save(control);
			}

			systemService.deleteActionBulletinByActionNo(actionNo);
			adminService.replaceUserRoleWithNewRole(agent.getRefUser(), SystemConstant.AGENT_ROLE, SystemConstant.SYSTEM_USER);
		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}
		catch(Exception be){
			be.printStackTrace();
			throw new BaseException("error.approve.agent.registration");
		}
	}

	public void rejectAgentRegistration(Agent agent, User approver,String reason,String actionNo)throws BaseException{
		try{
			agent.setStatus(AgentConstant.AGENT_STATUS_REJECT_REG);
			agent.setModifiedBy(approver);
			agent.setModifiedDate(new Date());
			agent.setReason(reason);
			dao.update(agent);

			systemService.deleteActionBulletinByActionNo(actionNo);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException("error.reject.agent.registration");
		}
	}

	//sub agent
	public List<Agent> getSubAgent(Agent agent)throws BaseException{
		try{
			return dao.getSubAgentList(agent.getAgentId());
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.sub.agent", new Object[]{}));
		}
	}

	public void createSubAgent(Agent subAgent,Agent agent,User createUser)throws BaseException{
		try{
			List<Agent> list = dao.getSubAgentCodeNameList(agent.getAgentId(), subAgent.getCode());
			if(list.size()>0){
				throw new BaseException(SpringUtils.getMessage("error.duplicate.sub.agent", new Object[]{}));
			}

			subAgent.setCreatedBy(createUser);
			subAgent.setCreatedDate(new Date());
			subAgent.setParent(agent);
			subAgent.setIsDeleted(CommonConstant.NOT_DELETED);


			User user =adminService.createNewUserWithRole(subAgent.getEmail(), 
					SystemConstant.DEFAULT_PASSWORD, SystemConstant.AGENT_SUB_ROLE, SystemConstant.SYSTEM_USER);
			subAgent.setRefUser(user);
			dao.save(subAgent);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.create.sub.agent", new Object[]{}));
		}
	}

	public void editSubAgent(Agent subAgent,Agent agent,User createUser)throws BaseException{
		try{
			List<Agent> list = dao.getSubAgentCodeNameList(agent.getAgentId(), subAgent.getCode());
			if(list.size()>0){
				for(Agent a:list){
					if(!a.getAgentId().equalsIgnoreCase(subAgent.getAgentId())){
						throw new BaseException(SpringUtils.getMessage("error.duplicate.sub.agent", new Object[]{}));
					}
				}
			}

			subAgent.setModifiedBy(createUser);
			subAgent.setModifiedDate(new Date());
			dao.merge(subAgent);

		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.edit.sub.agent", new Object[]{}));
		}
	}

	public void deleteSubAgent(List<Agent> agentList,User createUser)throws BaseException{
		try{
			for(Agent agent:agentList){
				if(agent.isMarkAsAction()){
					agent.setModifiedBy(createUser);
					agent.setModifiedDate(new Date());
					agent.setIsDeleted(CommonConstant.IS_DELETED);
					adminService.deActiveUser(agent.getRefUser(), createUser, false);
					dao.update(agent);
				}
			}



		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.delete.sub.agent", new Object[]{}));
		}
	}

	public List<Agent> getAgentListByType(String type)throws BaseException{
		try{

			return dao.getAgentListByLevel(type);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.agent", new Object[]{}));
		}
	}

	public List<Agent> searchRegNoPartnerNameInList(String regno,String name,List<Agent> agentList)throws BaseException{

		List<Agent> alist = new ArrayList<Agent>();

		if(regno==null){
			regno="";
		}
		if(name==null){
			name="";
		}

		if(name.length()==0&&regno.length()==0){
			return agentList;
		}

		for(Agent a :agentList){
			if(a.getAgentRegNo().equalsIgnoreCase(regno)){
				alist.add(a);
				continue;
			}
			if(a.getCompName().equalsIgnoreCase(name)){
				alist.add(a);
				continue;
			}
		}

		return alist;
	}

	public List<AgreementControl> getAgreementControlList(Agent agent)throws BaseException{
		try{

			return dao.getAgreementControlByAgentId(agent.getAgentId());

		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.agent.agreement.control", new Object[]{}));
		}
	}

	public void createAgreementControl(AgreementControl control,User createUser)throws BaseException{
		try{
			control.setCreatedBy(createUser);
			control.setCreatedDate(new Date());
			control.setIsDeleted(CommonConstant.NOT_DELETED);
			dao.save(control);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.create.agent.agreement.control", new Object[]{}));
		}
	}

	public void editAgreementControl(AgreementControl control,User user)throws BaseException{
		try{
			control.setModifiedBy(user);
			control.setModifiedDate(new Date());
			dao.update(control);
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.edit.agent.agreement.control", new Object[]{}));
		}
	}

	public void deleteAgreementControl(List<AgreementControl> controllist,User user)throws BaseException{
		try{
			for(AgreementControl control:controllist){
				control.setModifiedBy(user);
				control.setModifiedDate(new Date());
				control.setIsDeleted(CommonConstant.IS_DELETED);
				dao.update(control);
			}
		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.delete.agent.agreement.control", new Object[]{}));
		}
	}

	
	public void processAgentCommissionPyament(Agreement agreement,Payment payment,User user) throws Exception{
		Agent agent = agreement.getAgent();
		if(agent!=null){
			CommissionSchema schema = agent.getSchema();
			if(schema.getAccumulateType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_ACC_TYPE_NON_ACC)){
				//max pay
				AgentCommission commission = dao.getAgentCommissionByAgreementIdAgentId(agent.getAgentId(), agreement.getAgreementId());
				double paid = commission.getPaidDbl();
				double needTopaid = paid +  payment.getPaymentAmount().doubleValue();
				if(paid<commission.getMaxPayableDbl()){
					if(needTopaid<commission.getMaxPayableDbl()){
						needTopaid = payment.getPaymentAmount().doubleValue();
					}else{
						needTopaid = commission.getMaxPayableDbl() -  payment.getPaymentAmount().doubleValue();
					}
					AgentCommissionPayment agentCommissionPayment = new AgentCommissionPayment();
					agentCommissionPayment.setAgent(agent);
					agentCommissionPayment.setAgentCommission(commission);
					agentCommissionPayment.setStatus(AgentConstant.AGENT_COMM_PAYMENT_PENDING);
					agentCommissionPayment.setAmount(payment.getPaymentAmount());
					agentCommissionPayment.setCreatedBy(user);
					agentCommissionPayment.setCreatedDate(new Date());
					dao.save(agentCommissionPayment);
					
					commission.setPaid(new Double(paid+needTopaid));
					commission.setModifiedBy(user);
					commission.setModifiedDate(new Date());
					dao.update(commission);
				}else{
					//pay to max pay
					return;
				}
				
			}else{
				Calendar cal = GregorianCalendar.getInstance();
				cal.setTime(new Date());
				int month = cal.get(Calendar.MONTH);
				int year = cal.get(Calendar.YEAR);

				Integer monthInt = new Integer(month+1);
				Integer yearInt = new Integer(year);
				AgentCommission commission = dao.getAgentCommissionByDate(monthInt, yearInt, agent.getAgentId());
				
				
			}
			
		}
		
	}

	//commission
	public void calculateAgreementCommission(Agreement agreement,Agent agent)throws Exception{

		//Commission Schema
		CommissionSchema schema = agent.getSchema();
		double maxPay = 0;

		Double value = agreement.getMembership().getMembershipFee();
		//calculate base on range find max pay
		if(schema.getAccumulateType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_ACC_TYPE_NON_ACC)){
			
			System.out.println("---value="+value);
			System.out.println("---type="+schema.getType());
			
			//if(schema.getType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
			if(schema.getCommissionType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
				CommissionSchemaPaymentRange range = null; //comment by jimmy dao.getCommissionSchemaPaymentRangeBySchId(schema.getCommSchId(),value);
				if(range!=null){
					double percentValue = range.getPercentDbl()/100;
					maxPay = percentValue*value;
				}
			}
			//calculate base on category find max pay
			//else if(schema.getType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_CAT)){
			else if(schema.getCommissionType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_CAT)){
				CommissionSchemaMembership csm = dao.getCommissionSchemaMembership(agreement.getMembership().getMembershipId(), 
						schema.getCommSchId());

				System.out.println("---csm.getType()="+csm.getType());
				System.out.println("---csm.getValueDbl()="+csm.getValueDbl());
				if(csm.getType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_VAL_TYPE_VAL)){
					maxPay = csm.getValueDbl();
				}else{
					double percentVal = csm.getValueDbl()/100;
					maxPay = percentVal* value.doubleValue();
					System.out.println("---percentVal="+percentVal);
				}
			}
			System.out.println("---maxPay="+maxPay);
			AgentCommission commission = new AgentCommission();
			commission.setAgent(agent);
			commission.setMaxPayable(new Double(maxPay));
			commission.setType(AgentConstant.AGENT_COMM_SCH_ACC_TYPE_NON_ACC);
			commission.setCreatedBy(SystemConstant.SYSTEM_USER);
			commission.setCreatedDate(new Date());
			commission.setAgreement(agreement);
			commission.setIsDeleted(CommonConstant.NOT_DELETED);
			dao.save(commission);
		}else{

			Calendar cal = GregorianCalendar.getInstance();
			cal.setTime(new Date());
			int month = cal.get(Calendar.MONTH);
			int year = cal.get(Calendar.YEAR);

			Integer monthInt = new Integer(month+1);
			Integer yearInt = new Integer(year);
			AgentCommission commission = dao.getAgentCommissionByDate(monthInt, yearInt, agent.getAgentId());
			double accAmt = 0;
			if(commission==null){
				commission = new AgentCommission();
				commission.setAccumulateAmount(agreement.getMembership().getMembershipFee());
				commission.setAgent(agent);
				commission.setType(AgentConstant.AGENT_COMM_SCH_ACC_TYPE_ACC);
				commission.setCreatedBy(SystemConstant.SYSTEM_USER);
				commission.setCreatedDate(new Date());
				commission.setMonth(monthInt);
				commission.setYear(yearInt);
				commission.setIsDeleted(CommonConstant.NOT_DELETED);
				dao.save(commission);
				accAmt = commission.getAccumulateAmount();
			}else{
				accAmt = commission.getAccumulateAmount()+agreement.getMembership().getMembershipFee();
			}

			if(schema.getType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_RANGE)){
				CommissionSchemaPaymentRange range = null;//comment by jimmy dao.getCommissionSchemaPaymentRangeBySchId(schema.getCommSchId(),accAmt);
				if(range!=null){
					maxPay = range.getPercentDbl()*accAmt;
					commission.setMaxPayable(new Double(maxPay));
				}
			}
			//calculate base on category find max pay
			else if(schema.getType().equalsIgnoreCase(AgentConstant.AGENT_COMM_SCH_COMM_TYPE_CAT)){
				//TODO
			}

			dao.update(commission);
		}
	}

	public List<AgentCommission> getAgentCommissionListByDateRange(String agentId,Date from,Date to)throws BaseException{
		try{

			if(from!=null&&to!=null){
				Calendar fromCal = GregorianCalendar.getInstance();
				fromCal.setTime(from);
				fromCal.set(Calendar.MINUTE, 0);
				fromCal.set(Calendar.HOUR, 0);
				fromCal.set(Calendar.SECOND, 0);
				from = fromCal.getTime();

				Calendar toCal = GregorianCalendar.getInstance();
				toCal.setTime(to);
				toCal.set(Calendar.MINUTE, 0);
				toCal.set(Calendar.HOUR, 0);
				toCal.set(Calendar.SECOND, 0);
				to = toCal.getTime();
			}


			return dao.getAgentCommissionListByDateRange(agentId, from, to);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.get.agent.commission.list", new Object[]{}));
		}
	}
	
	public void updateAgentProfileAction(Agent agent,User user)throws BaseException{
		try{
			agent.setModifiedBy(user);
			agent.setModifiedDate(new Date());
			dao.update(agent);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.update.agent.profile", new Object[]{}));
		}
	}
}
